package kbpost

import (
	"context"
	"strconv"
	"strings"

	"mall/common/utils/pointy"
	"mall/service/backend/api/internal/logic/utils"
	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/backend/rpc/backendclient"
	"mall/service/blog/rpc/blogclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type RecommendPostListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewRecommendPostListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RecommendPostListLogic {
	return &RecommendPostListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *RecommendPostListLogic) RecommendPostList(req *types.RecommendPostListReq) (resp *types.RecommendPostListResp, err error) {
	var objectType string
	reqType := strings.TrimSpace(req.Type)
	if len(reqType) > 0 {
		objectType = reqType
	} else {
		objectType = "brand"
	}

	res, err := l.svcCtx.BackendRpc.RecommendPostList(l.ctx, &backendclient.RecommendPostListReq{
		Date: req.Date,
		Type: objectType,
	})
	if err != nil {
		return nil, err
	}

	switch objectType {
	case "brand":
		var eids []string
		dateIdsMap := make(map[int32][]int64)
		if len(res.List) > 0 {
			for _, item := range res.List {
				eid := strconv.FormatInt(item.EntryId, 10)
				eids = append(eids, eid)
				dateIdsMap[item.StartDate] = append(dateIdsMap[item.StartDate], item.EntryId)
			}
		}

		return l.recommendBrandList(eids, dateIdsMap)
	}

	return &types.RecommendPostListResp{}, nil
}

func (l *RecommendPostListLogic) recommendBrandList(
	eids []string,
	dateIdsMap map[int32][]int64,
) (resp *types.RecommendPostListResp, err error) {
	res, err := l.svcCtx.BlogRpc.BackendGetKBPostList(l.ctx, &blogclient.TmpKBPostListReq{
		Ids: pointy.GetPointer(strings.Join(eids, ",")),
	})
	if err != nil {
		return nil, err
	}

	idMap := make(map[uint64]*types.KBEntryInfo)
	if len(res.List) > 0 {
		for _, v := range res.List {
			var sections []*types.CMSTermInfo
			if len(v.Sections) > 0 {
				for _, v := range v.Sections {
					sections = append(sections, &types.CMSTermInfo{
						BaseIDInfo: types.BaseIDInfo{
							Id: v.Id,
						},
						Name: v.Name,
						Slug: v.Slug,
					})
				}
			}

			var media []*types.MediaInfo
			if len(v.Media) > 0 {
				for _, m := range v.Media {
					var url string
					if m.Url != nil && len(*m.Url) > 0 {
						url = *m.Url
					}
					if len(url) == 0 && m.Uri != nil && len(*m.Uri) > 0 {
						url = *m.Uri
					}
					filename, mimeType, metaData := utils.ParseMetaData(m.MetaData)
					media = append(media, &types.MediaInfo{
						Uid:       m.Uid,
						Id:        m.Id,
						Thumbnail: m.Thumbnail,
						Order:     m.Order,
						Url:       pointy.GetPointer(url),
						Name:      pointy.GetPointer(filename),
						MimeType:  pointy.GetPointer(mimeType),
						AltText:   m.AltText,
						MetaData:  pointy.GetPointer(metaData),
					})
				}
			}

			idMap[*v.Id] = &types.KBEntryInfo{
				BaseIDInfo: types.BaseIDInfo{
					Id:        v.Id,
					CreatedAt: v.CreatedAt,
					UpdatedAt: v.UpdatedAt,
				},
				Title:    v.Title,
				Slug:     v.Slug,
				Uri:      v.Uri,
				Excerpt:  v.Excerpt,
				Status:   v.Status,
				ParentId: v.ParentId,
				Section:  sections,
				Media:    media,
			}
		}
	}

	list := make(map[int32][]*types.KBEntryInfo)
	for date, ids := range dateIdsMap {
		for _, id := range ids {
			if entry, ok := idMap[uint64(id)]; ok {
				list[date] = append(list[date], entry)
			}
		}
	}

	return &types.RecommendPostListResp{
		List:  list,
		Total: int64(res.Total),
	}, nil
}
